﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Web7.FilterProviders;
using Web7.Mvc.ActionInvokers;
using Web7.Core.ControllerFactories;
using Web7.Mvc.ViewEngines;
using Web7.Core.ViewResolvers;
using Web7.Core.ActionFilters.Result;
using Web7.Domain;
using Web7.Mvc.ModelBinders;
using NHibernate;

namespace Web7.Core.Apps.Core
{
    public class CoreApp : App
    {
        #region IModule Members

        public override string AppName
        {
            get { return "Core"; }
        }

        public override void Initialize()
        {
            //设置DI映射
            SetupContainer();
            //设置控制器工厂
            SetupControllerFactory();
            //注册视图引擎
            RegisterViewEngines();
            //注册FilterProviders
            RegisterFilterProviders();
            //注册视图解析器
            RegisterViewResolvers();
            //注册Hibernate
            RegisterNHibernate();
        }

        public override void RegisterFilters(FilterRegistryFilterProvider filterRegistry, GlobalFilterCollection globalFilters)
        {
            //// 如果是调试模式，则设置View["Debug"]为true
            //// 比如，在View中可以获取ViewData["Debug"]的值来判断是否是调试模式
            //filterRegistry.Add(null, typeof(DebugActionFilter));
            //// SiteActionFilter 站点基本信息
            //filterRegistry.Add(null, typeof(SiteActionFilter));
            //// UserActionFilter 将UserViewModel和MembershipUrlViewModel加入至 Web7ViewModule
            //filterRegistry.Add(null, typeof(UserActionFilter));
            //// ReturnUrl 加入至 Web7ViewModule
            //filterRegistry.Add(null, typeof(ReturnUrlActionFilter));
            //// 防止CSRF攻击
            //filterRegistry.Add(null, typeof(AntiForgeryAuthorizationFilter));
            // ViewEnginesResultFilter,ViewEngines设置
            // Viewning 从这里开始
            filterRegistry.Add(null, typeof(ViewEnginesResultFilter));
#if RELEASE
            // 异常处理,由于异常页要通过Viewning来查找视图，所以要放在ViewEnginesResultFilter之后
            filterRegistry.Add(null, typeof(ErrorExceptionFilter));
#endif
        }

        public override void RegisterModelBinders(ModelBinderDictionary modelBinders)
        {
            //modelBinders[typeof(PagingInfo)] = DependencyInjector.GetService<PagingInfoModelBinder>();
            modelBinders[typeof(List<Guid>)] = DependencyInjector.GetService<GuidListModelBinder>();
            modelBinders[typeof(List<Int32>)] = DependencyInjector.GetService<Int32ListModelBinder>();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 设置DI映射
        /// </summary>
        private void SetupContainer()
        {
            DependencyInjector
                .RegisterType<IActionInvoker, Web7ControllerActionInvoker>();
                //.RegisterType<IViewResolverRegistry, ViewResolverRegistry>();

            //DependencyInjector
            //    .RegisterType<IFormsAuthentication, FormsAuthenticationWrapper>();

        }

        /// <summary>
        /// 设置控制器工厂
        /// <remarks>主要目的是在ControllerFactory的GetControllerInstance方法中获取Controller实例后，重新设置其ActionInvoker</remarks>
        /// </summary>
        private void SetupControllerFactory()
        {
            //方式1：
            //实现一个IControllerFactory并RegisterType注册，不能再使用SetControllerFactory设置
            //DependencyInjector.RegisterType<IControllerFactory, DependencyInjectorControllerFactory>();
            //方式2：
            //实现一个IControllerFactory创建对象，再使用SetControllerFactory设置
            ControllerBuilder.Current.SetControllerFactory(DependencyInjector.GetService<DependencyInjectorControllerFactory>());
            //方式3：
            //实现一个IControllerActivator，如：NewControllerActivator,并RegisterType注册
            //DependencyInjector.RegisterType<IControllerActivator, NewControllerActivator>();
            //方式4：
            //实现一个IControllerActivator，如：NewControllerActivator,并创建对象
            //再使用DefaultControllerFactory(IControllerActivator controllerActivator)构造
            //最后使用SetControllerFactory设置
            //IControllerActivator activator = new NewControllerActivator();
            //DefaultControllerFactory controllerFactory = new DefaultControllerFactory(activator);
            //ControllerBuilder.Current.SetControllerFactory(controllerFactory);

        }

        /// <summary>
        /// 注册视图引擎
        /// </summary>
        private void RegisterViewEngines()
        {
            //获取ASP.NET MVC内置的视图引擎
            ViewEngineCollection viewEngines = DependencyInjector.GetService<ViewEngineCollection>();
            viewEngines.Clear();

            //Modified By  :HaiJun
            //Modified Date:2012-4-5
            //Description  : 注释掉这一句，系统里面没有WebForm的视图引擎
            //viewEngines.Add(DependencyInjector.GetService<Web7WebFormViewEngine>());

            viewEngines.Add(DependencyInjector.GetService<Web7RazorViewEngine>());
        }

        /// <summary>
        /// 注册FilterProviders
        /// </summary>
        private void RegisterFilterProviders()
        {
            FilterProviderCollection filterProviders = DependencyInjector.GetService<FilterProviderCollection>();
            filterProviders.Add(DependencyInjector.GetService<FilterRegistryFilterProvider>());
        }

        /// <summary>
        /// 注册视图解析器
        /// </summary>
        private void RegisterViewResolvers()
        {
            IViewResolverRegistry viewResolverRegistry = DependencyInjector.GetService<ViewResolverRegistry>();
            viewResolverRegistry.Default = DependencyInjector.GetService<Web7ViewResolver>();

            //移动设备
            //Modified By  :HaiJun
            //Modified Date:2012-4-5
            //Description  : 注释掉这一句，因为目前没有手机的视图
            //viewResolverRegistry.Add(DependencyInjector.GetService<MobileViewResolver>());
            
            //IE6、IE7和IE8等Hacks
            //移动设备
            //Modified By  :HaiJun
            //Modified Date:2012-4-5
            //Description  : 注释掉这一句,目前没有这方面的需求
            //viewResolverRegistry.Add(DependencyInjector.GetService<LegacyViewResolver>());

            DependencyInjector.RegisterInstance(viewResolverRegistry);
        }

        private void RegisterNHibernate()
        {
            ISessionFactory sessionFactory = new NHibernate.Cfg.Configuration().Configure().BuildSessionFactory();
            DependencyInjector.RegisterInstance<ISessionFactory>(sessionFactory);
        }

        #endregion
    }
}
